home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / UNIXUNIX.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  9KB  |  382 lines

  1. /*    SCCS Id: @(#)unixunix.c    3.0    88/04/13
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* This file collects some Unix dependencies; pager.c contains some more */
  6.  
  7. /*
  8.  * The time is used for:
  9.  *    - seed for rand()
  10.  *    - year on tombstone and yymmdd in record file
  11.  *    - phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
  12.  *    - night and midnight (the undead are dangerous at midnight)
  13.  *    - determination of what files are "very old"
  14.  */
  15.  
  16. /* block some unused #defines to avoid overloading some cpp's */
  17. #define MONATTK_H
  18. #define MONFLAG_H
  19. #include "hack.h"    /* mainly for index() which depends on BSD */
  20.  
  21. #include <errno.h>
  22. #include <sys/stat.h>
  23. #ifdef NO_FILE_LINKS
  24. #include <fcntl.h>
  25. #endif
  26.  
  27. void
  28. setrandom()
  29. {
  30. #if defined(SYSV) || defined(DGUX)
  31.     (void) Srand((long) time ((time_t *) 0));
  32. #else
  33. #ifdef ULTRIX
  34.     Srand((int)time((time_t *)0));
  35. #else
  36.     (void) Srand((int) time ((long *) 0));
  37. #endif /* ULTRIX */
  38. #endif /* SYSV */
  39.  
  40. }
  41.  
  42. static struct tm *
  43. getlt()
  44. {
  45.     time_t date;
  46.  
  47. #ifdef BSD
  48.     (void) time((long *)(&date));
  49. #else
  50.     (void) time(&date);
  51. #endif
  52. #if defined(ULTRIX) || defined(BSD)
  53.     return(localtime((long *)(&date)));
  54. #else
  55.     return(localtime(&date));
  56. #endif /* ULTRIX */
  57. }
  58.  
  59. int
  60. getyear()
  61. {
  62.     return(1900 + getlt()->tm_year);
  63. }
  64.  
  65. char *
  66. getdate()
  67. {
  68. #ifdef LINT    /* static char datestr[7]; */
  69.     char datestr[7];
  70. #else
  71.     static char datestr[7];
  72. #endif
  73.     register struct tm *lt = getlt();
  74.  
  75.     Sprintf(datestr, "%2d%2d%2d",
  76.         lt->tm_year, lt->tm_mon + 1, lt->tm_mday);
  77.     if(datestr[2] == ' ') datestr[2] = '0';
  78.     if(datestr[4] == ' ') datestr[4] = '0';
  79.     return(datestr);
  80. }
  81.  
  82. int
  83. phase_of_the_moon()            /* 0-7, with 0: new, 4: full */
  84. {                    /* moon period: 29.5306 days */
  85.                     /* year: 365.2422 days */
  86.     register struct tm *lt = getlt();
  87.     register int epact, diy, goldn;
  88.  
  89.     diy = lt->tm_yday;
  90.     goldn = (lt->tm_year % 19) + 1;
  91.     epact = (11 * goldn + 18) % 30;
  92.     if ((epact == 25 && goldn > 11) || epact == 24)
  93.         epact++;
  94.  
  95.     return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
  96. }
  97.  
  98. int
  99. night()
  100. {
  101.     register int hour = getlt()->tm_hour;
  102.  
  103.     return(hour < 6 || hour > 21);
  104. }
  105.  
  106. int
  107. midnight()
  108. {
  109.     return(getlt()->tm_hour == 0);
  110. }
  111.  
  112. static struct stat buf, hbuf;
  113.  
  114. void
  115. gethdate(name) char *name; {
  116. /* old version - for people short of space */
  117. /*
  118. /* register char *np;
  119. /*    if(stat(name, &hbuf))
  120. /*        error("Cannot get status of %s.",
  121. /*            (np = rindex(name, '/')) ? np+1 : name);
  122. /*
  123. /* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */
  124.  
  125.  
  126. /*
  127.  * The problem with   #include    <sys/param.h>   is that this include file
  128.  * does not exist on all systems, and moreover, that it sometimes includes
  129.  * <sys/types.h> again, so that the compiler sees these typedefs twice.
  130.  */
  131. #define        MAXPATHLEN    1024
  132.  
  133. register char *np, *path;
  134. char filename[MAXPATHLEN+1];
  135.     if (index(name, '/') != NULL || (path = getenv("PATH")) == NULL)
  136.         path = "";
  137.  
  138.     for (;;) {
  139.         if ((np = index(path, ':')) == NULL)
  140.             np = path + strlen(path);    /* point to end str */
  141.         if (np - path <= 1)            /* %% */
  142.             Strcpy(filename, name);
  143.         else {
  144.             (void) strncpy(filename, path, np - path);
  145.             filename[np - path] = '/';
  146.             Strcpy(filename + (np - path) + 1, name);
  147.         }
  148.         if (stat(filename, &hbuf) == 0)
  149.             return;
  150.         if (*np == '\0')
  151.             break;
  152.         path = np + 1;
  153.     }
  154.     error("Cannot get status of %s.",
  155.         (np = rindex(name, '/')) ? np+1 : name);
  156. }
  157.  
  158. int
  159. uptodate(fd)
  160. int fd;
  161. {
  162.     if(fstat(fd, &buf)) {
  163.         pline("Cannot get status of saved level? ");
  164.         return(0);
  165.     }
  166.     if(buf.st_mtime < hbuf.st_mtime) {
  167.         pline("Saved level is out of date. ");
  168.         return(0);
  169.     }
  170.     return(1);
  171. }
  172.  
  173. /* see whether we should throw away this xlock file */
  174. static int
  175. veryold(fd)
  176. int fd;
  177. {
  178.     time_t date;
  179.  
  180.     if(fstat(fd, &buf)) return(0);            /* cannot get status */
  181.     if(buf.st_size != sizeof(int)) return(0);    /* not an xlock file */
  182. #ifdef BSD
  183.     (void) time((long *)(&date));
  184. #else
  185.     (void) time(&date);
  186. #endif
  187.     if(date - buf.st_mtime < 3L*24L*60L*60L) {    /* recent */
  188.         extern int errno;
  189.         int lockedpid;    /* should be the same size as hackpid */
  190.  
  191.         if(read(fd, (char *)&lockedpid, sizeof(lockedpid)) !=
  192.             sizeof(lockedpid))
  193.             /* strange ... */
  194.             return(0);
  195.  
  196.         /* From: Rick Adams <seismo!rick>
  197.         /* This will work on 4.1cbsd, 4.2bsd and system 3? & 5.
  198.         /* It will do nothing on V7 or 4.1bsd. */
  199. #ifndef NETWORK
  200.         /* It will do a VERY BAD THING if the playground is shared
  201.            by more than one machine! -pem */
  202.           if(!(kill(lockedpid, 0) == -1 && errno == ESRCH))
  203. #endif
  204.             return(0);
  205.     }
  206.     (void) close(fd);
  207.     return(1);
  208. }
  209.  
  210. static int
  211. eraseoldlocks()
  212. {
  213.     register int i;
  214.  
  215.     for(i = 1; i <= MAXLEVEL+1; i++) {        /* try to remove all */
  216.         glo(i);
  217.         (void) unlink(lock);
  218.     }
  219.     glo(0);
  220.     if(unlink(lock)) return(0);            /* cannot remove it */
  221.     return(1);                    /* success! */
  222. }
  223.  
  224. void
  225. getlock()
  226. {
  227.     extern int errno;
  228.     register int i = 0, fd, c;
  229. #ifdef NO_FILE_LINKS
  230.     int hlockfd ;
  231.     int sleepct = 20 ;
  232. #endif
  233.  
  234. #ifdef HARD
  235.     /* idea from rpick%ucqais@uccba.uc.edu
  236.      * prevent automated rerolling of characters
  237.      * test input (fd0) so that tee'ing output to get a screen dump still
  238.      * works
  239.      * also incidentally prevents development of any hack-o-matic programs
  240.      */
  241.     if (!isatty(0))
  242.         error("You must play from a terminal.");
  243. #endif
  244.  
  245.     (void) fflush(stdout);
  246.  
  247.     /* we ignore QUIT and INT at this point */
  248. #ifdef NO_FILE_LINKS
  249.     while ((hlockfd = open(LLOCK,O_RDONLY|O_CREAT|O_EXCL,0644)) == -1) {
  250.         if (--sleepct) {
  251.         Printf( "Lock file in use.  %d retries left.\n",sleepct);
  252.         (void) fflush(stdout);
  253. # if defined(SYSV) || defined(ULTRIX)
  254.         (void)
  255. # endif
  256.             sleep(1);
  257.         } else {
  258.         Printf("I give up!  Try again later.\n");
  259.         getret();
  260.         error("");
  261.         }
  262.     }
  263.     (void) close(hlockfd);
  264.  
  265. #else    /* NO_FILE_LINKS */
  266.     if (link(HLOCK, LLOCK) == -1) {
  267.         register int errnosv = errno;
  268.  
  269.         perror(HLOCK);
  270.         Printf("Cannot link %s to %s\n", LLOCK, HLOCK);
  271.         switch(errnosv) {
  272.         case ENOENT:
  273.             Printf("Perhaps there is no (empty) file %s ?\n", HLOCK);
  274.             break;
  275.         case EACCES:
  276.             Printf("It seems you don't have write permission here.\n");
  277.             break;
  278.         case EEXIST:
  279.             Printf("(Try again or rm %s.)\n", LLOCK);
  280.             break;
  281.         default:
  282.             Printf("I don't know what is wrong.");
  283.         }
  284.         getret();
  285.         error("");
  286.         /*NOTREACHED*/
  287.     }
  288. #endif /* NO_FILE_LINKS */
  289.  
  290.     regularize(lock);
  291.     glo(0);
  292.  
  293.     if(locknum) {
  294.         if(locknum > 25) locknum = 25;
  295.  
  296.         do {
  297.             lock[0] = 'a' + i++;
  298.  
  299.             if((fd = open(lock, 0)) == -1) {
  300.                 if(errno == ENOENT) goto gotlock; /* no such file */
  301.                 perror(lock);
  302.                 (void) unlink(LLOCK);
  303.                 error("Cannot open %s", lock);
  304.             }
  305.  
  306.             if(veryold(fd) /* closes fd if true */
  307.                             && eraseoldlocks())
  308.                 goto gotlock;
  309.             (void) close(fd);
  310.         } while(i < locknum);
  311.  
  312.         (void) unlink(LLOCK);
  313.         error("Too many hacks running now.");
  314.     } else {
  315.         if((fd = open(lock, 0)) == -1) {
  316.             if(errno == ENOENT) goto gotlock;    /* no such file */
  317.             perror(lock);
  318.             (void) unlink(LLOCK);
  319.             error("Cannot open %s", lock);
  320.         }
  321.  
  322.         if(veryold(fd) /* closes fd if true */ && eraseoldlocks())
  323.             goto gotlock;
  324.         (void) close(fd);
  325.  
  326.         Printf("\nThere is already a game in progress under your name.");
  327.         Printf("\nDestroy old game? [yn] ");
  328.         (void) fflush(stdout);
  329.         c = Getchar();
  330.         while (Getchar() != '\n') ; /* eat rest of line and newline */
  331.         if(c == 'y' || c == 'Y')
  332.             if(eraseoldlocks())
  333.                 goto gotlock;
  334.             else {
  335.                 (void) unlink(LLOCK);
  336.                 error("Couldn't destroy old game.");
  337.             }
  338.         else {
  339.             (void) unlink(LLOCK);
  340.             error("");
  341.         }
  342.     }
  343. gotlock:
  344.     fd = creat(lock, FCMASK);
  345.     if(unlink(LLOCK) == -1)
  346.         error("Cannot unlink %s.", LLOCK);
  347.     if(fd == -1) {
  348.         error("cannot creat lock file.");
  349.     } else {
  350.         if(write(fd, (char *) &hackpid, sizeof(hackpid))
  351.             != sizeof(hackpid)){
  352.             error("cannot write lock");
  353.         }
  354.         if(close(fd) == -1) {
  355.             error("cannot close lock");
  356.         }
  357.     }
  358. }    
  359.  
  360. void
  361. regularize(s)    /* normalize file name - we don't like .'s, /'s, spaces */
  362. register char *s;
  363. {
  364.     register char *lp;
  365.  
  366.     while((lp=index(s, '.')) || (lp=index(s, '/')) || (lp=index(s,' ')))
  367.         *lp = '_';
  368. #ifdef SYSV
  369.     /* avoid problems with 14 character file name limit */
  370. # ifdef COMPRESS
  371.     if(strlen(s) > 10)
  372.         /* leave room for .e from error and .Z from compress
  373.          * appended to save files */
  374.         s[10] = '\0';
  375. # else
  376.     if(strlen(s) > 11)
  377.         /* leave room for .nn appended to level files */
  378.         s[11] = '\0';
  379. # endif
  380. #endif
  381. }
  382.